﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
using System.Xml.Linq;

namespace _11_Generic
{
    internal class MyList<T>
    {
        Node<T> root;
        public int Length { get; private set; }

        public MyList()
        {
            root = null;
            Length = 0;
        }

        public Node<T> Add(Node<T> node)
        {
            // 当前链表已经包含了这个节点
            if (Find(node) != null)
            {
                return Add(new Node<T>(node.Data));
            }
            // 如果根节点是空
            if (root == null)
            {
                // 那就初始化根节点
                root = node;
                Length++;
                return root; // 如果不加 即使是第一次进 下面的代码也会执行
            }
            Node<T> current = root;
            // 查找当前节点的next是否为空 如果是 则找到了结尾
            while(current.Next != null)
            {
                current = current.Next;
            }
            // 在结尾添加新的节点
            current.SetNext(node);
            Length++;
            return node;
        }
        public void Delete()
        {
            if (root == null || Length == 0)
            {
                return;
            }
            if(Length == 1)
            {
                root = null;
                Length = 0;
                return;
            }
            Node<T>? current = root;
            Node<T>? previous = current;
            // 查找当前节点的next是否为空 如果是 则找到了结尾
            while (current != null && current.Next != null)
            {
                previous = current;
                current = current.Next;
            }
            // C#的垃圾回收 当某段内存我们无法访问 系统就会自动回收
            if (previous != null)
            {
                previous.SetNext(null);
            }
            Length--;
        }

        // 插到某一个Node之前
        public void Insert(Node<T> node,Node<T> target)
        {
            if (target == root)
            {
                node.SetNext(root);
                root = node;
                Length++;
                return;
            }
            Node<T>? previous = Find(target,true);
            node.SetNext(target);
            previous.SetNext(node);
            Length++;
        }

        public void Remove(Node<T> node)
        {
            if (node == root)
            {
                root = node.Next;
                node = null;
                Length--;
                return;
            }
            Node<T>? previous = Find(node, true);
            if (previous == null)
            {
                Console.WriteLine("Node不在本链表中");
                return;
            }
            previous.SetNext(node.Next);
            node = null;
            Length--;
        }

        public void Clear()
        {
            Node<T>? current = root;
            Node<T>previous = current;

            while (current != null && current.Next != null)
            {
                current = current.Next;
            }
            root = null;
            Length = 0;
        }

        public Node<T> Find(Node<T> node, bool preview = false)
        {
            Node<T>? current = root;

            while (current != null && current != node)
            {
                if(preview && current.Next == node)
                {
                    return current;
                }
                current = current.Next;
            }

            return current;
        }

        public void Print()
        {
            Node<T> current = root;
            while (current != null)
            {
                Console.Write(current.Data + " ");
                current = current.Next;
            }
            Console.WriteLine($"\nLenght:{Length}");
        }
    }
}
